﻿//
// encoding.hpp
// ~~~~~~~~~~~~
//

#ifndef WEBAPP_ENCODING_HPP
#define WEBAPP_ENCODING_HPP

#include <string>

#include <boost/type_traits.hpp>

#define __USING_SJIS__
#define __UNICODE_CHAR_SIZE_2__
#define __LITTLE_ENDIAN_COMPUTER__	//
#define __BBL_STRING_DEFAULT__
#include <babel.h>
#include <babel.cpp>

namespace webapp
{
	namespace encoding
	{
		const static struct initializer
		{
			initializer()
			{
				babel::init_babel();
			}
		} init;

		//utf8
		babel::bbl_binary inline u8( const std::string& from )
		{
			return babel::auto_translate<babel::bbl_binary>( from, babel::base_encoding::utf8 );
		}
		babel::bbl_binary inline u8( const std::wstring& from )
		{
			return babel::unicode_to_utf8( from );
		}

		//sjis
		babel::bbl_binary inline sjis( const std::string& from )
		{
			return babel::auto_translate<babel::bbl_binary>( from, babel::base_encoding::sjis );
		}
		babel::bbl_binary inline sjis( const std::wstring& from )
		{
			return babel::unicode_to_sjis( from );
		}

		//unicode
		babel::bbl_wstring inline u16( const std::string& from )
		{
			return babel::auto_translate<babel::bbl_wstring>( from, babel::base_encoding::unicode );
		}
		babel::bbl_wstring inline u16( const std::wstring& from )
		{
			return from;
		}

		struct u8_t
		{
			typedef std::string		result_type;

			result_type operator()( const std::string& from ) const
			{
				return u8( from );
			}

			result_type operator()( const std::wstring& from ) const
			{
				return u8( from );
			}

			static const char* name()
			{
				return "UTF-8";
			}
		};

		struct u16_t
		{
			typedef std::wstring	result_type;

			result_type operator()( const std::string& from ) const
			{
				return u16( from );
			}

			result_type operator()( const std::wstring& from ) const
			{
				return u16( from );
			}

			//never use
			static const char* name()
			{
				return "*";
			}
		};

		struct sjis_t
		{
			typedef std::string		result_type;

			result_type operator()( const std::string& gen ) const
			{
				return sjis( gen );
			}
			result_type operator()( const std::wstring& gen ) const
			{
				return sjis( gen );
			}

			static const char* name()
			{
				return "Shift_JIS";
			}
		};

		template<class Encoder, class Decoder>
		struct translator
		{
			typedef typename boost::remove_reference<
				typename boost::remove_cv<Encoder>::type
			>::type	encoder_type;
			typedef typename boost::remove_reference<
				typename boost::remove_cv<Decoder>::type
			>::type	decoder_type;
		};
	} // - encoding
} // - webapp

#endif /*WEBAPP_ENCODING_HPP*/
